package service

import (
	"crypto/x509"
	"encoding/pem"
	"errors"
	"hp-server-lib/bean"
	"hp-server-lib/db"
	"hp-server-lib/entity"
	"hp-server-lib/net/acme"
	"log"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

var acmeCheck int32 = 0

var DOMAIN_INFO = sync.Map{}

type DomainService struct {
}

func InitDomainCache() {
	page := 1
	pageSize := 100
	for {
		var results []*entity.UserDomainEntity
		tx := db.DB.Model(&entity.UserDomainEntity{}).
			Offset((page - 1) * pageSize).
			Limit(pageSize).
			Find(&results)
		if tx.Error != nil {
			break
		}
		// 如果本页没有数据，说明结束
		if len(results) == 0 {
			break
		}
		// 放入缓存
		for _, r := range results {
			DOMAIN_INFO.Store(*r.Domain, r)
		}
		// 下一页
		page++
	}
}

func (receiver *DomainService) DomainList(userId int, page int, pageSize int) *bean.ResPage {
	var results []*entity.UserDomainEntity
	var total int64
	if userId < 0 {
		db.DB.Model(&entity.UserDomainEntity{}).Order("id desc").Count(&total).Offset((page - 1) * pageSize).Limit(pageSize).Find(&results)
	} else {
		db.DB.Model(&entity.UserDomainEntity{}).Where("user_id = ?", userId).Order("id desc").Count(&total).Offset((page - 1) * pageSize).Limit(pageSize).Find(&results)
	}

	for _, data := range results {
		if len(data.CertificateKey) > 0 && len(data.CertificateContent) > 0 {
			// 解码 PEM 数据
			block, _ := pem.Decode([]byte(data.CertificateContent))
			if block == nil {
				data.Tips = "证书格式错误.."
				continue
			}
			// 解析证书
			cert, err := x509.ParseCertificate(block.Bytes)
			if err != nil {
				log.Printf(err.Error())
				data.Tips = "证书格式错误."
				continue
			} else {
				// 获取当前时间
				now := time.Now()
				// 检查证书是否过期
				if now.After(cert.NotAfter) {
					data.Tips = "证书已经过期"
				} else {
					duration := cert.NotAfter.Sub(now)
					daysRemaining := int(duration.Hours() / 24)
					data.Tips = "证书还有" + strconv.Itoa(daysRemaining) + "天过期"
				}
			}
		} else {
			data.Tips = "无证书"
		}
	}

	if userId < 0 {
		var userIds []int
		for _, item := range results {
			userIds = append(userIds, *item.UserId)
		}
		var users []*entity.UserCustomEntity
		if err := db.DB.Model(&entity.UserCustomEntity{}).Where("id IN ?", userIds).Find(&users).Error; err == nil {
			// 将查询结果转换成 map[int]User
			userMap := make(map[int]*entity.UserCustomEntity)
			for _, user := range users {
				userMap[*user.Id] = user
			}
			for _, item := range results {
				customEntity := userMap[*item.UserId]
				if customEntity != nil {
					item.Username = customEntity.Username
					item.UserDesc = customEntity.Desc
				}
			}
		}
	}
	// 计算总记录数并执行分页查询
	return bean.PageOk(total, results)
}

func (receiver *DomainService) DomainListByKey(userId int, keyword string) *bean.ResData {
	var results []entity.UserDomainEntity
	if userId < 0 {
		tx := db.DB.Model(&entity.UserDomainEntity{})
		tx.Joins("LEFT JOIN user_config ON user_domain.domain = user_config.domain LEFT JOIN user_reverse ON user_domain.domain = user_reverse.domain")
		if len(keyword) > 0 {
			tx.Where("(user_config.domain is null or user_config.domain='') and (user_reverse.domain is null or user_reverse.domain='') and user_domain.domain like ?", "%"+keyword+"%")
		} else {
			tx.Where("(user_config.domain is null or user_config.domain='') and (user_reverse.domain is null or user_reverse.domain='') ")
		}

		tx.Order("user_domain.id desc").Find(&results)
	} else {
		model := db.DB.Model(&entity.UserDomainEntity{})
		model.Joins("LEFT JOIN user_config ON user_domain.domain = user_config.domain LEFT JOIN user_reverse ON user_domain.domain = user_reverse.domain")
		if len(keyword) > 0 {
			model.Where("(user_config.domain is null or user_config.domain='') and (user_reverse.domain is null or user_reverse.domain='') and user_domain.domain like ? and user_domain.user_id = ? ", "%"+keyword+"%", userId)
		} else {
			model.Where("(user_config.domain is null or user_config.domain='') and (user_reverse.domain is null or user_reverse.domain='') and user_domain.user_id = ?", userId)
		}
		model.Order("user_domain.id desc").Find(&results)
	}
	return bean.ResOk(results)
}

func (receiver *DomainService) RemoveData(id int) bool {
	userQuery := &entity.UserDomainEntity{}
	db.DB.Where("id = ? ", id).First(userQuery)
	if userQuery != nil {
		var results entity.UserDomainEntity
		db.DB.Where("id = ?", id).Delete(&results)
		DOMAIN_INFO.Delete(*userQuery.Domain)
		return true
	}
	return false
}

func (receiver *DomainService) AddData(userDomain entity.UserDomainEntity) error {
	userDomain.CertificateContent = strings.TrimSpace(userDomain.CertificateContent)
	userDomain.CertificateKey = strings.TrimSpace(userDomain.CertificateKey)
	if userDomain.Id == nil {
		var total int64
		db.DB.Model(&entity.UserDomainEntity{}).Where("domain = ?", strings.TrimSpace(*userDomain.Domain)).Count(&total)
		if total > 0 {
			return errors.New("域名已存在")
		}
		db.DB.Save(&userDomain)
		DOMAIN_INFO.Store(*userDomain.Domain, &userDomain)
	} else {
		//更新缓存
		value, ok := DOMAIN_INFO.Load(*userDomain.Domain)
		if ok {
			info := value.(*entity.UserDomainEntity)
			info.CertificateKey = userDomain.CertificateKey
			info.CertificateContent = userDomain.CertificateContent
		}
		db.DB.Model(&entity.UserDomainEntity{}).Where("id = ?", userDomain.Id).Update("certificate_content", userDomain.CertificateContent).Update("certificate_key", userDomain.CertificateKey).Update("desc", userDomain.Desc)
	}
	return nil
}

func (receiver *DomainService) GenSsl(sync bool, id int) bool {
	userQuery := &entity.UserDomainEntity{}
	db.DB.Where("id = ? ", id).First(userQuery)
	if userQuery != nil {
		// 使用atomic.CompareAndSwap原子操作检查和设置值
		receiver.UpdateStatus(id, "证书获取中...")
		if sync {
			flag := false
			if atomic.CompareAndSwapInt32(&acmeCheck, 0, 1) {
				// 如果值是0（没有值），则设置为1（已设置）并执行代码
				cert, err := acme.ConfigAcme.GenCert(*userQuery.Domain)
				if err != nil {
					receiver.UpdateStatus(id, "证书获取失败:"+err.Error())
				} else {
					receiver.UpdateData(id, string(cert.PrivateKey), string(cert.Certificate), *userQuery.Domain)
					receiver.UpdateStatus(id, "证书获取完成")
					flag = true
				}
				atomic.StoreInt32(&acmeCheck, 0)
			} else {
				receiver.UpdateStatus(id, "已经有证书在生成完成后再试")
			}
			return flag
		} else {
			go func() {
				if atomic.CompareAndSwapInt32(&acmeCheck, 0, 1) {
					// 如果值是0（没有值），则设置为1（已设置）并执行代码
					cert, err := acme.ConfigAcme.GenCert(*userQuery.Domain)
					if err != nil {
						receiver.UpdateStatus(id, "证书获取失败:"+err.Error())
					} else {
						receiver.UpdateData(id, string(cert.PrivateKey), string(cert.Certificate), *userQuery.Domain)
						receiver.UpdateStatus(id, "证书获取完成")
					}
					atomic.StoreInt32(&acmeCheck, 0)
				} else {
					receiver.UpdateStatus(id, "已经有证书在生成完成后再试")
				}
			}()
		}
		return true
	}
	return false
}

func (receiver *DomainService) UpdateData(id int, key, content string, domain string) {
	//更新域名配置
	db.DB.Model(&entity.UserDomainEntity{}).Where("id = ?", id).Update("certificate_key", key).Update("certificate_content", content)
	//更新缓存
	value, ok := DOMAIN_INFO.Load(domain)
	if ok {
		info := value.(*entity.UserDomainEntity)
		info.CertificateKey = key
		info.CertificateContent = content
	}
}

func (receiver *DomainService) UpdateStatus(id int, status string) {
	db.DB.Model(&entity.UserDomainEntity{}).Where("id = ?", id).Update("status", status)
}
